/*******************************************************************************
**
** Copyright (c) 2010, All Rights Reserved.
**
** File:       flash_bin_make.c
** Created By: Ji Guoping
** Created On: 06/27/2011
**
** Purpose:
** This file to make bin files burn on flash in manufacture,combine boot and app2.
**
** revision 1.0
**
*******************************************************************************/
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <assert.h>

#define BOOT_MAX_LEN        0xC000UL	//0x8000UL      /* boot bin file max length, 32K bytes */
#define APP_MAX_LEN         0x18000UL      /* app bin file max length, 128K bytes */
#define FLASH_SIZE          BOOT_MAX_LEN + APP_MAX_LEN     /* program flash size, 256K bytes */

//#define DEBUG 1
/********************file occupy******************
0x00000 ----- 0x7FFF        boot file
0x08000 ----- 0x1ffff       app file
*************************************************/
/* common data type define */
typedef char INT8;
typedef unsigned char UINT8;
typedef short int INT16;
typedef unsigned short int UINT16;
typedef int INT32;
typedef unsigned int UINT32;

int main (int argc, INT8 *argv[])
{
	INT8 tmp;
    UINT8 pad_len = 0;
	UINT8 *buf_p, *tmp_p;
	FILE *boot_file, *ap_file, *new_file;
	UINT32 boot_len, ap_len;
    INT32 ret;
	INT32 nleft;

#ifndef DEBUG
	if(argc != 4)
	{
         printf("Usage: binmake <boot bin file> <app bin file> <output bin file>");
	     return 1;
	}	
	/* boot bin file */
    boot_file = fopen(argv[1], "rb");
	if (NULL == boot_file)
	{
		printf("can't open file %s\n", argv[1]);
		return 1;
	}
#else
	boot_file = fopen("boot.bin", "rb");
#endif
	ret = fseek(boot_file, 0, SEEK_END);
    if (ret < 0)
        return 1;
    boot_len = ftell(boot_file);
	if (boot_len > BOOT_MAX_LEN)
	{
		printf("boot bin file too long!\n");
		return 1;
	}
    ret = fseek(boot_file, 0, SEEK_SET);
    if(ret < 0)
        return 1;

	/* app bin file */
#ifndef DEBUG
    ap_file = fopen(argv[2], "rb");

	if (NULL == ap_file)
	{
		printf("can't open file %s\n", argv[2]);
		return 1;
	}
#else 
	ap_file = fopen("app.bin", "rb");
#endif
    ret = fseek(ap_file, 0, SEEK_END);
    if (ret < 0)
        return 1;
    ap_len = ftell(ap_file);
	if (ap_len > APP_MAX_LEN)
	{
		printf("app bin file too long!\n");
		return 1;
	}
    ret = fseek(ap_file, 0, SEEK_SET);
    if(ret < 0)
        return 1;


    buf_p = (UINT8*)malloc(FLASH_SIZE);
	if (NULL == buf_p)
		return 1;
	memset(buf_p, 0, FLASH_SIZE);
    tmp_p = buf_p;
    /* write boot bin to buf */
	nleft = boot_len;
	while(nleft > 0)
	{
		ret = fread(tmp_p, sizeof(INT8), nleft, boot_file);
		if(ret < 0)
			return 1;
		nleft -= ret;
		tmp_p += ret;
	}
	tmp_p += BOOT_MAX_LEN - boot_len;
	ret = fseek(ap_file, 0, SEEK_SET);
	if(ret < 0)
		return 1;

    /* write app bin to buf */
    nleft = ap_len;
	while(nleft > 0)
    {
        ret = fread(tmp_p, sizeof(INT8), nleft, ap_file);
        if(ret < 0)
            return 1;
        nleft -= ret;
        tmp_p += ret;
    }
	/*should add left block*/
	tmp_p += APP_MAX_LEN - ap_len;

	/* write buf to flash bin file */
#ifndef DEBUG
	new_file = fopen(argv[3], "wb+");
	if (NULL == new_file)
	{
		printf("can't open file %s\n", argv[3]);
		return 1;
	}
#else
	new_file = fopen("all.bin", "wb+");
#endif
	tmp_p = buf_p;
	nleft = FLASH_SIZE;
	while(nleft > 0)
    {
        ret = fwrite(tmp_p, sizeof(INT8), nleft, new_file);
        if(ret < 0)
            return 1;
        nleft -= ret;
        tmp_p += ret;
    }

	ret = fflush(new_file);
	if (ret != 0)
		return 1;
	ret = fclose(new_file);
	if (ret != 0)
		return 1;
	fclose(boot_file);
	if (ret != 0)
		return 1;
	fclose(ap_file);
	if (ret != 0)
		return 1;

	free(buf_p);

    return 0;
}